package star.cloud.asme.base.file.fileInfo;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import star.cloud.asme.base.dto.Result;
import star.cloud.asme.base.file.cosClient.CosClientService;
import star.cloud.asme.base.mybatis.IBaseServiceImpl;

import java.util.Collection;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class FileInfoServiceImpl extends IBaseServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {

    private final FileInfoMapper fileInfoMapper;

    private final CosClientService cosClientService;

    @Override
    public Result<FileInfo> getOneByCondition(String columnName, Object columnValue) {
        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
        switch (columnName) {
            case "id" -> queryWrapper.eq(FileInfo::getId, columnValue);
            case "keyWord" -> queryWrapper.eq(FileInfo::getKeyWord, columnValue);
            default -> queryWrapper.like(FileInfo::getKeyWord, columnValue);
        }
        FileInfo fileInfo = fileInfoMapper.selectOne(queryWrapper);
        return Result.ok(fileInfo);
    }


    @Override
    @Transactional(rollbackOn = Exception.class)
    public FileInfo uploadOneFile(FileInfo fileInfo, MultipartFile file) {
        Collection<FileInfo> fileInfoList = getFileInfoListByKeyword(fileInfo.getKeyWord()).getBody();
        if (fileInfoList.isEmpty()) {
            fileInfo = handleInsertFile(fileInfo, file);
        } else {
            fileInfo = handleUpdateFile(fileInfo, file);
        }
        return fileInfo;
    }


    @Override
    public FileInfo appendOneFile(FileInfo fileInfo, MultipartFile file) {
        fileInfo = handleInsertFile(fileInfo, file);
        return fileInfo;
    }

    @Override
    public Result<List<FileInfo>> getFileInfoListByKeyword(String keyWord) {
        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileInfo::getKeyWord, keyWord);
        return Result.ok(fileInfoMapper.selectList(queryWrapper));
    }

    @Override
    public Result<FileInfo> getOneByKeyword(String keyWord) {
        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileInfo::getKeyWord, keyWord);
        FileInfo fileInfo = fileInfoMapper.selectOne(queryWrapper);
        return Result.ok(fileInfo);
    }

    @Override
    @Transactional
    public Result<?> physicalDeleteByUid(Long uid) {
        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileInfo::getUid, uid);
        FileInfo fileInfo = fileInfoMapper.selectOne(queryWrapper);
        fileInfoMapper.deleteById(fileInfo.getId());
        fileInfoMapper.deleteByUid(uid);
        cosClientService.deleteFile(fileInfo);
        return Result.ok(true);
    }

    @Override
    public Result<?> physicalDeleteByKeyWord(String keyWord) {
        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileInfo::getKeyWord, keyWord);
        FileInfo fileInfo = fileInfoMapper.selectOne(queryWrapper);
        fileInfoMapper.deleteById(fileInfo.getId());
        fileInfoMapper.deleteByKeyWord(keyWord);
        cosClientService.deleteFile(fileInfo);
        return Result.ok(true);
    }

    @Override
    public Result<?> physicalDeleteById(Long id) {
        FileInfo fileInfo = fileInfoMapper.selectById(id);
        cosClientService.deleteFile(fileInfo);
        fileInfoMapper.deleteById(id);
        fileInfoMapper.physicalDeleteById(id);
        return Result.ok();
    }

    @Override
    public FileInfo getFileInfoByKeyword(String keyWord) {
        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileInfo::getKeyWord, keyWord);
        return fileInfoMapper.selectOne(queryWrapper);
    }

    private FileInfo handleInsertFile(FileInfo fileInfo, MultipartFile file) {
        fileInfo = cosClientService.uploadInputStream(fileInfo, file);
        fileInfoMapper.insert(fileInfo);
        return fileInfo;
    }

    private FileInfo handleUpdateFile(FileInfo fileInfo, MultipartFile file) {
        FileInfo fileInfo1 = fileInfoMapper.selectOneByKeyWord(fileInfo.getKeyWord());
        cosClientService.deleteFile(fileInfo1);
        FileInfo uploaded = cosClientService.uploadInputStream(fileInfo, file);
        uploaded.setId(fileInfo1.getId());
        setVersion(fileInfo);
        fileInfoMapper.updateById(uploaded);
        return fileInfoMapper.selectById(uploaded.getId());
    }

}